#include "variantinput.h"
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtCore/QFile>
#include <QtCore/QDataStream>

VariantInput::VariantInput(const QVariant & var, QWidget * parent, Qt::WindowFlags f)
	: QWidget(parent, f)
{
	QVBoxLayout *vBox = new QVBoxLayout(this);
	view = new QTableView(this);
	vBox->addWidget(view);

	QHBoxLayout* hBox = new QHBoxLayout();
	addButton = new QPushButton(tr("Add"),this);
	connect(addButton, SIGNAL(clicked()), this, SLOT(addRow()));
	delButton = new QPushButton(tr("Delete"), this);
	connect(delButton, SIGNAL(clicked()), this, SLOT(deleteRow()));
	QPushButton *commit = new QPushButton(tr("Commit"), this);
	connect(commit, SIGNAL(clicked()), this, SIGNAL(commit()));
	//QFrame *vline = new QFrame(this);
	//vline->setFrameShape(QFrame::VLine);
	//QPushButton *save = new QPushButton(tr("Save"), this);
	//connect(save, SIGNAL(clicked()), this, SLOT(save()));
	//QPushButton *read = new QPushButton(tr("Read"), this);
	//connect(read, SIGNAL(clicked()), this, SLOT(read()));
	hBox->addStretch(1);
	hBox->addWidget(addButton);
	hBox->addWidget(delButton);
	hBox->addWidget(commit);
	//hBox->addWidget(vline);
	//hBox->addWidget(save);
	//hBox->addWidget(read);

	vBox->addLayout(hBox);

	model = new VariantModel(var, this);
	//freshButton();
	//connect(model, SIGNAL(modelReset()), this, SLOT(freshButton()));
	view->setModel(model);
	connect(view, SIGNAL(clicked(const QModelIndex &)), 
		this, SLOT(editCollection(const QModelIndex &)));

	mDefaultDelegate = view->itemDelegate();
	mTypeDelegate = new TypeDelegate(this);
	setDelegate();
	connect(model, SIGNAL(modelReset()), this, SLOT(setDelegate()));

	//setWindowTitle(QString("Type:%1").arg(QVariant::typeToName(var.type())));
}

VariantInput::~VariantInput()
{

}

QVariant VariantInput::value()
{
	return model->value();
}

void VariantInput::setValue(const QVariant& value)
{
	model->setVariant(value);
}

void VariantInput::addRow()
{
	model->append(QVariant("http://sites.google.com/site/dunanshan"), QString("Nosense"));
}

void VariantInput::deleteRow()
{
	model->deleteAt(view->currentIndex());
}

void VariantInput::commitData()
{
	VariantInput* collect = static_cast<VariantInput*>(sender());
	model->setData(mIndex, collect->value());
	collect->close();
}

void VariantInput::freshButton()
{
	if (model->isCollection(model->value().type())) {
		addButton->setEnabled(true);
		if (view->currentIndex().isValid())
			delButton->setEnabled(true);
	}else {
		addButton->setEnabled(false);
		delButton->setEnabled(false);
	}
}

//void VariantInput::save()
//{
//	QFile file("data.txt");
//	if (!file.open(QIODevice::WriteOnly)) 
//		return;
//	QDataStream stream(&file);
//	stream << model->value();
//	file.close();
//}
//
//void VariantInput::read()
//{
//	QFile file("data.txt");
//	if (!file.open(QIODevice::ReadOnly)) 
//		return;
//	QDataStream stream(&file);
//	QVariant var;
//	stream >> var;
//	file.close();
//	model->setVariant(var);
//}

void VariantInput::editCollection(const QModelIndex & index)
{
	QVariant var = model->data(index);
	if (model->isCollection(var.type())) {
		mIndex = index;
		VariantInput *collect = new VariantInput(var, this);
		collect->setAttribute(Qt::WA_DeleteOnClose);
		connect(collect, SIGNAL(commit()), this, SLOT(commitData()));
		collect->setWindowFlags(Qt::Dialog);
		collect->setWindowModality(Qt::WindowModal);
		collect->show();
	}
}

void VariantInput::setDelegate()
{
	int column = model->columnCount();
	if (column==3) //to Map, column 1 should reset to default QItemDelegate
		view->setItemDelegateForColumn(column-2, mDefaultDelegate);

	//view->setItemDelegateForColumn(column-1,mTypeDelegate);
	/************************************************************************
	**  phenomenon: result in that widget isn't sensitive with keyboard and mouse input?
	**  result:     setData only occurs when mouse click on another item,
	**              items are difficult to lose the focus.
	**  want:       renew the keyboard and mouse sensitive.
	**  cause:      mTypeDelegate is set to itself, so not connect signals with slots.
	**              in qabstractitemview.cpp line 739 d->delegateRefCount(delegate) == 0 is false.
	**  solution:   avoid the itemDelegate to be self-assigned.
	*************************************************************************/
	//view->setItemDelegateForColumn(column-1,0); //or mDefaultDelegate 
	//view->setItemDelegateForColumn(column-1,mTypeDelegate);

	//avoid to itemDelegate self-assigned.
	if (mTypeDelegate != view->itemDelegateForColumn(column-1)) 
		view->setItemDelegateForColumn(column-1,mTypeDelegate);
}

//void VariantInput::setTitle()
//{
//	setWindowTitle(QString("Type:%1").arg(QVariant::typeToName(model->value().type())));
//}
